package cn.xiaolang.function.data_structure;

import org.apache.commons.lang3.RandomStringUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.util.*;


/**
 * 测试一致性hash算法
 *
 * @author Dean
 * @date 2021-10-25
 */
public class DistributedHashTest {

    private DistributedHash<String> hosts;

    @Before
    public void init() {
        hosts = new DistributedHash<>(Arrays.asList("x.x.10.100", "x.x.10.101", "x.x.10.102"));
    }

    @Test
    public void testTreeMapTail() {
        // creating maps
        TreeMap<Integer, String> treemap = new TreeMap<>();
        // populating tree map
        treemap.put(2, "two");
        treemap.put(1, "one");
        treemap.put(3, "three");
        treemap.put(6, "six");
        treemap.put(5, "five");
        // First key
        Assert.assertEquals(Integer.valueOf(1), treemap.firstKey());
        Integer targetKey = 4;
        // tail map : 5,6
        SortedMap<Integer, String> splitResult = treemap.tailMap(targetKey);
        Assert.assertEquals(2, splitResult.size());
        for (Integer key : splitResult.keySet()) {
            Assert.assertTrue(key > targetKey);
        }
        // head map : 1,2,3
        splitResult = treemap.headMap(targetKey);
        Assert.assertEquals(3, splitResult.size());
        for (Integer key : splitResult.keySet()) {
            Assert.assertTrue(key < targetKey);
        }

    }

    @Test
    public void testEqual() {
        String key = "dean";
        String firstGet = hosts.getShardInfo(key);
        String secondGet = hosts.getShardInfo(key);
        Assert.assertEquals(firstGet, secondGet);
    }

    @Test
    public void testLB() {
        Map<String, Integer> count = new HashMap<>();
        for (int i = 0; i < 10000; i++) {
            String shardInfo = hosts.getShardInfo(RandomStringUtils.randomAlphabetic(6));
            count.put(shardInfo, Objects.isNull(count.get(shardInfo)) ? 1 : count.get(shardInfo) + 1);
        }
        System.out.println(count);
    }
}
